package cn.sfrog.project.biz.admin.service.impl;

import cn.sfrog.common.core.domain.entity.SysUser;
import cn.sfrog.common.exception.ApiException;
import cn.sfrog.common.utils.DateUtils;
import cn.sfrog.common.utils.SecurityUtils;
import cn.sfrog.common.utils.StringUtils;
import cn.sfrog.project.biz.admin.domain.*;
import cn.sfrog.project.biz.admin.domain.vo.BizUserRechargePaymentFormVO;
import cn.sfrog.project.biz.admin.domain.vo.BizUserRechargePaymentQueryVO;
import cn.sfrog.project.biz.admin.domain.vo.BizUserRechargePaymentVO;
import cn.sfrog.project.biz.admin.enums.BizUserTradeTypeEnum;
import cn.sfrog.project.biz.admin.mapper.*;
import cn.sfrog.project.biz.admin.service.IBizUserCommissionService;
import cn.sfrog.project.biz.admin.service.IBizUserRechargePaymentService;
import cn.sfrog.project.biz.admin.service.IBizUserTradeRecordService;
import cn.sfrog.project.biz.web.vo.account.AppUserRechargeFormVO;
import cn.sfrog.system.domain.vo.BizStatusChangeVO;
import cn.sfrog.system.mapper.SysUserMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;


/**
 * 支付Service业务层处理
 */
@Service
public class BizUserRechargePaymentServiceImpl extends ServiceImpl<BizUserRechargePaymentMapper, BizUserRechargePayment> implements IBizUserRechargePaymentService {
    @Resource
    private BizUserRechargePaymentMapper bizUserRechargePaymentMapper;
    @Resource
    private BizUserRechargeMapper bizUserRechargeMapper;
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private IBizUserTradeRecordService bizUserTradeRecordService;
    @Resource
    private BizUserTradeRecordMapper bizUserTradeRecordMapper;
    @Resource
    private BizUserAccountMapper bizUserAccountMapper;
    @Resource
    private BizUserEnsureMoneyMapper bizUserEnsureMoneyMapper;
    @Resource
    private IBizUserCommissionService bizUserCommissionService;

    /**
     * 查询支付
     *
     * @param id 支付主键
     * @return 支付
     */
    @Override
    public BizUserRechargePaymentVO selectBizUserRechargePaymentById(Long id) {
        return bizUserRechargePaymentMapper.selectBizUserRechargePaymentById(id);
    }

    /**
     * 查询支付列表
     *
     * @param query 支付
     * @return 支付
     */
    @Override
    public List<BizUserRechargePaymentVO> selectBizUserRechargePaymentList(BizUserRechargePaymentQueryVO query) {
        return bizUserRechargePaymentMapper.selectBizUserRechargePaymentList(query);
    }

    /**
     * 新增支付
     *
     * @param form 支付
     * @return 结果
     */
    @Transactional(rollbackFor = Throwable.class)
    @Override
    public boolean insertBizUserRechargePayment(BizUserRechargePaymentFormVO form) {
        BizUserRechargePayment bizUserRechargePayment = new BizUserRechargePayment();
        BeanUtils.copyProperties(form, bizUserRechargePayment);
        bizUserRechargePayment.setCreateTime(new Date());
        bizUserRechargePayment.setCreateBy(SecurityUtils.getUsername());
        bizUserRechargePayment.setUpdateTime(new Date());
        bizUserRechargePayment.setUpdateBy(SecurityUtils.getUsername());
        return bizUserRechargePayment.insert();
    }

    /**
     * 修改支付
     *
     * @param form 支付
     * @return 结果
     */
    @Transactional(rollbackFor = Throwable.class)
    @Override
    public boolean updateBizUserRechargePayment(BizUserRechargePaymentFormVO form) {
        BizUserRechargePayment bizUserRechargePayment = new BizUserRechargePayment();
        BeanUtils.copyProperties(form, bizUserRechargePayment);
        bizUserRechargePayment.setUpdateTime(new Date());
        bizUserRechargePayment.setUpdateBy(SecurityUtils.getUsername());
        return bizUserRechargePayment.updateById();
    }

    /**
     * 批量删除支付
     *
     * @param ids 需要删除的支付主键
     * @return 结果
     */
    @Transactional(rollbackFor = Throwable.class)
    @Override
    public boolean deleteBizUserRechargePaymentByIds(Long[] ids) {
        return BizUserRechargePayment.DAO.delete(Wrappers.lambdaQuery(BizUserRechargePayment.class).in(BizUserRechargePayment::getId, (Object[]) ids));
    }

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public boolean changeStatus(BizStatusChangeVO vo) {
        //return BizUserRechargePayment.DAO.update(Wrappers.lambdaUpdate(BizUserRechargePayment.class).in(BizUserRechargePayment::getId, (Object[]) vo.getIds()).set(BizUserRechargePayment::getStatus, vo.getStatus()));
        return true;
    }

    @Override
    public BizUserRechargePayment createRechargePayment(String rechargeSerialNumber, AppUserRechargeFormVO form, Long userId) {
        BizUserRechargePayment payment = new BizUserRechargePayment();
        payment.setRechargeSerialNumber(rechargeSerialNumber);
        payment.setRechargeAmount(form.getRechargeAmount());
        payment.setPaymentAmount(form.getPaymentAmount());
        payment.setType(BizUserRechargePayment.TYPE_RECHARGE);
        payment.setPayUserId(userId);
        payment.setCreateTime(DateUtils.getNowDate());
        payment.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserName());
        bizUserRechargePaymentMapper.insert(payment);
        return payment;
    }


    @Override
    public BizUserRechargePayment createEnsureMoneyPayment(BizUserEnsureMoney userEnsureMoney, SysUser user) {
        BizUserRechargePayment payment = new BizUserRechargePayment();
        payment.setRechargeSerialNumber(userEnsureMoney.getSerialNumber());
        payment.setRechargeAmount(userEnsureMoney.getAmount());
        payment.setPaymentAmount(userEnsureMoney.getAmount());
        payment.setType(BizUserRechargePayment.TYPE_ENSURE_MONEY);
        payment.setPayUserId(user.getUserId());
        payment.setCreateTime(DateUtils.getNowDate());
        payment.setCreateBy(user.getUserName());
        bizUserRechargePaymentMapper.insert(payment);
        return payment;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void paySuccess(String tradeNo, String aliTradeNo, Date payTime) {
        LambdaQueryWrapper<BizUserRechargePayment> wrapper = new LambdaQueryWrapper<BizUserRechargePayment>();
        wrapper.eq(BizUserRechargePayment::getRechargeSerialNumber, tradeNo);
        BizUserRechargePayment payment = bizUserRechargePaymentMapper.selectOne(wrapper);
        if (payment == null) {
            log.warn("支付回调找不到payment信息编号：" + tradeNo);
            throw new ApiException("找不到payment信息");
        }
        if (BizUserRechargePayment.PAY_STATUS_NO.equals(payment.getPayStatus())) {
            BizRechargeUnit bizRechargeUnit = new BizRechargeUnit();
            //回调成功的业务处理 支付流水表
            payment.setPayTime(payTime);
            payment.setRealMoney(payment.getRechargeAmount());
            payment.setSerialNumber(aliTradeNo);
            payment.setPayStatus(BizUserRechargePayment.PAY_STATUS_YES);
            payment.setPayType(BizUserRechargePayment.ALI_PAY);
            payment.setUpdateBy(payment.getCreateBy());
            payment.setUpdateTime(DateUtils.getNowDate());
            bizUserRechargePaymentMapper.updateById(payment);

            //交易记录表
            BizUserTradeRecord tradeRecord = new BizUserTradeRecord();
            tradeRecord.setUserId(payment.getPayUserId());
            tradeRecord.setTradeTime(DateUtils.getNowDate());
            tradeRecord.setUpdateBy(payment.getPayUserId().toString());
            tradeRecord.setUpdateTime(DateUtils.getNowDate());
            tradeRecord.setCreateBy(payment.getPayUserId().toString());
            tradeRecord.setCreateTime(DateUtils.getNowDate());

            if(BizUserRechargePayment.TYPE_RECHARGE.equals(payment.getType())){
                //充值 找到充值记录信息
                LambdaQueryWrapper<BizUserRecharge> queryWrapper = new LambdaQueryWrapper<BizUserRecharge>()
                        .eq(BizUserRecharge::getSerialNumber, tradeNo);
                BizUserRecharge recharge = bizUserRechargeMapper.selectOne(queryWrapper);
                if (recharge == null) {
                    throw new ApiException("充值信息不存在");
                }
                recharge.setPayStatus(BizUserRecharge.PAY_STATUS_YES);
                recharge.setPaymentId(payment.getId());
                recharge.setUpdateBy(recharge.getCreateBy());
                recharge.setUpdateTime(DateUtils.getNowDate());
                bizUserRechargeMapper.updateById(recharge);
                Boolean customizeFlag = true;
                if(BizUserRecharge.IS_CUSTOMIZE_NO.equals(recharge.getIsCustomize())){
                    bizRechargeUnit = BizRechargeUnit.DAO.selectById(recharge.getRechargeUnitId());
                    customizeFlag = false;
                }
                tradeRecord.setTradeAmount(customizeFlag ? payment.getRechargeAmount() : payment.getRechargeAmount().add(new BigDecimal(bizRechargeUnit.getGiveAwayCount())));
                tradeRecord.setType(BizUserTradeTypeEnum.RECHARGE.getCode());
                tradeRecord.setSerialNumber(recharge.getSerialNumber());
                tradeRecord.setRemark(customizeFlag ? "充值": "充值(赠送"+bizRechargeUnit.getGiveAwayCount()+"陪护豆)");

                //更新用户账户余额
                LambdaQueryWrapper<BizUserAccount> queryWrapper1 = new LambdaQueryWrapper<BizUserAccount>()
                        .eq(BizUserAccount::getUserId, payment.getPayUserId());
                BizUserAccount bizUserAccount = BizUserAccount.DAO.selectOne(queryWrapper1);
                if (bizUserAccount != null) {
                    bizUserAccount.setUpdateBy(bizUserAccount.getCreateBy());
                    bizUserAccount.setUpdateTime(DateUtils.getNowDate());
                    bizUserAccount.setAccountBalance(bizUserAccount.getAccountBalance().add(payment.getRechargeAmount()));
                    //判断是否自定义充值 否=会赠送 是=不赠送
                    if(!customizeFlag){
                        if(StringUtils.isNotNull(bizRechargeUnit)){
                            bizUserAccount.setGiveAwayAmount(bizUserAccount.getGiveAwayAmount().add(new BigDecimal(bizRechargeUnit.getGiveAwayCount())));
                        }
                    }
                    bizUserAccountMapper.updateById(bizUserAccount);
                }
                SysUser dbUser = sysUserMapper.selectUserById(payment.getPayUserId());
                SysUser sysUser = new SysUser();
                sysUser.setUserId(payment.getPayUserId());
//                if(customizeFlag){
//                    sysUser.setEscortBeanCount(dbUser.getEscortBeanCount().add(payment.getRechargeAmount()));
//                }else {
//                    sysUser.setEscortBeanCount(dbUser.getEscortBeanCount().add(payment.getRechargeAmount()).add(new BigDecimal(bizRechargeUnit.getGiveAwayCount())));
//                }
                sysUser.setEscortBeanCount(bizUserAccount.getAccountBalance().add(bizUserAccount.getGiveAwayAmount()).add(bizUserAccount.getCommissionAmount()));
                sysUserMapper.updateUser(sysUser);

                //记录分佣
                bizUserCommissionService.saveUserCommission(recharge,dbUser);
            }else if(BizUserRechargePayment.TYPE_ENSURE_MONEY.equals(payment.getType())){
                //保证金
                LambdaQueryWrapper<BizUserEnsureMoney> lambdaQueryWrapper = new LambdaQueryWrapper<BizUserEnsureMoney>()
                        .eq(BizUserEnsureMoney::getSerialNumber,tradeNo);
                BizUserEnsureMoney money = BizUserEnsureMoney.DAO.selectOne(lambdaQueryWrapper);
                if(StringUtils.isNotNull(money)){
                    tradeRecord.setTradeAmount(payment.getRechargeAmount().negate());
                    tradeRecord.setType(BizUserTradeTypeEnum.ENSURE_MONEY.getCode());
                    tradeRecord.setSerialNumber(money.getSerialNumber());
                    tradeRecord.setRemark("交保证金");

                    money.setPayTime(payTime);
                    money.setPayStatus(BizUserRechargePayment.PAY_STATUS_YES);
                    money.setUpdateTime(DateUtils.getNowDate());
                    money.setUserName(money.getCreateBy());
                    bizUserEnsureMoneyMapper.updateById(money);
                }
            }

            bizUserTradeRecordMapper.insert(tradeRecord);
        }
    }

}
